home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Berkeley DB 1.8.5a / include / sys⁄queue.h < prev   
Text File  |  1995-06-14  |  9KB  |  246 lines

  1. /* 
  2.  * Copyright (c) 1991, 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)queue.h    8.3 (Berkeley) 12/13/93
  34.  */
  35.  
  36. #ifndef    _QUEUE_H_
  37. #define    _QUEUE_H_
  38.  
  39. /*
  40.  * This file defines three types of data structures: lists, tail queues,
  41.  * and circular queues.
  42.  *
  43.  * A list is headed by a single forward pointer (or an array of forward
  44.  * pointers for a hash table header). The elements are doubly linked
  45.  * so that an arbitrary element can be removed without a need to
  46.  * traverse the list. New elements can be added to the list after
  47.  * an existing element or at the head of the list. A list may only be
  48.  * traversed in the forward direction.
  49.  *
  50.  * A tail queue is headed by a pair of pointers, one to the head of the
  51.  * list and the other to the tail of the list. The elements are doubly
  52.  * linked so that an arbitrary element can be removed without a need to
  53.  * traverse the list. New elements can be added to the list after
  54.  * an existing element, at the head of the list, or at the end of the
  55.  * list. A tail queue may only be traversed in the forward direction.
  56.  *
  57.  * A circle queue is headed by a pair of pointers, one to the head of the
  58.  * list and the other to the tail of the list. The elements are doubly
  59.  * linked so that an arbitrary element can be removed without a need to
  60.  * traverse the list. New elements can be added to the list before or after
  61.  * an existing element, at the head of the list, or at the end of the list.
  62.  * A circle queue may be traversed in either direction, but has a more
  63.  * complex end of list detection.
  64.  *
  65.  * For details on the use of these macros, see the queue(3) manual page.
  66.  */
  67.  
  68. /*
  69.  * List definitions.
  70.  */
  71. #define LIST_HEAD(name, type)                        \
  72. struct name {                                \
  73.     struct type *lh_first;    /* first element */            \
  74. }
  75.  
  76. #define LIST_ENTRY(type)                        \
  77. struct {                                \
  78.     struct type *le_next;    /* next element */            \
  79.     struct type **le_prev;    /* address of previous next element */    \
  80. }
  81.  
  82. /*
  83.  * List functions.
  84.  */
  85. #define    LIST_INIT(head) {                        \
  86.     (head)->lh_first = NULL;                    \
  87. }
  88.  
  89. #define LIST_INSERT_AFTER(listelm, elm, field) {            \
  90.     if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)    \
  91.         (listelm)->field.le_next->field.le_prev =        \
  92.             &(elm)->field.le_next;                \
  93.     (listelm)->field.le_next = (elm);                \
  94.     (elm)->field.le_prev = &(listelm)->field.le_next;        \
  95. }
  96.  
  97. #define LIST_INSERT_HEAD(head, elm, field) {                \
  98.     if (((elm)->field.le_next = (head)->lh_first) != NULL)        \
  99.         (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
  100.     (head)->lh_first = (elm);                    \
  101.     (elm)->field.le_prev = &(head)->lh_first;            \
  102. }
  103.  
  104. #define LIST_REMOVE(elm, field) {                    \
  105.     if ((elm)->field.le_next != NULL)                \
  106.         (elm)->field.le_next->field.le_prev =             \
  107.             (elm)->field.le_prev;                \
  108.     *(elm)->field.le_prev = (elm)->field.le_next;            \
  109. }
  110.  
  111. /*
  112.  * Tail queue definitions.
  113.  */
  114. #define TAILQ_HEAD(name, type)                        \
  115. struct name {                                \
  116.     struct type *tqh_first;    /* first element */            \
  117.     struct type **tqh_last;    /* addr of last next element */        \
  118. }
  119.  
  120. #define TAILQ_ENTRY(type)                        \
  121. struct {                                \
  122.     struct type *tqe_next;    /* next element */            \
  123.     struct type **tqe_prev;    /* address of previous next element */    \
  124. }
  125.  
  126. /*
  127.  * Tail queue functions.
  128.  */
  129. #define    TAILQ_INIT(head) {                        \
  130.     (head)->tqh_first = NULL;                    \
  131.     (head)->tqh_last = &(head)->tqh_first;                \
  132. }
  133.  
  134. #define TAILQ_INSERT_HEAD(head, elm, field) {                \
  135.     if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)    \
  136.         (elm)->field.tqe_next->field.tqe_prev =            \
  137.             &(elm)->field.tqe_next;                \
  138.     else                                \
  139.         (head)->tqh_last = &(elm)->field.tqe_next;        \
  140.     (head)->tqh_first = (elm);                    \
  141.     (elm)->field.tqe_prev = &(head)->tqh_first;            \
  142. }
  143.  
  144. #define TAILQ_INSERT_TAIL(head, elm, field) {                \
  145.     (elm)->field.tqe_next = NULL;                    \
  146.     (elm)->field.tqe_prev = (head)->tqh_last;            \
  147.     *(head)->tqh_last = (elm);                    \
  148.     (head)->tqh_last = &(elm)->field.tqe_next;            \
  149. }
  150.  
  151. #define TAILQ_INSERT_AFTER(head, listelm, elm, field) {            \
  152.     if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
  153.         (elm)->field.tqe_next->field.tqe_prev =         \
  154.             &(elm)->field.tqe_next;                \
  155.     else                                \
  156.         (head)->tqh_last = &(elm)->field.tqe_next;        \
  157.     (listelm)->field.tqe_next = (elm);                \
  158.     (elm)->field.tqe_prev = &(listelm)->field.tqe_next;        \
  159. }
  160.  
  161. #define TAILQ_REMOVE(head, elm, field) {                \
  162.     if (((elm)->field.tqe_next) != NULL)                \
  163.         (elm)->field.tqe_next->field.tqe_prev =         \
  164.             (elm)->field.tqe_prev;                \
  165.     else                                \
  166.         (head)->tqh_last = (elm)->field.tqe_prev;        \
  167.     *(elm)->field.tqe_prev = (elm)->field.tqe_next;            \
  168. }
  169.  
  170. /*
  171.  * Circular queue definitions.
  172.  */
  173. #define CIRCLEQ_HEAD(name, type)                    \
  174. struct name {                                \
  175.     struct type *cqh_first;        /* first element */        \
  176.     struct type *cqh_last;        /* last element */        \
  177. }
  178.  
  179. #define CIRCLEQ_ENTRY(type)                        \
  180. struct {                                \
  181.     struct type *cqe_next;        /* next element */        \
  182.     struct type *cqe_prev;        /* previous element */        \
  183. }
  184.  
  185. /*
  186.  * Circular queue functions.
  187.  */
  188. #define    CIRCLEQ_INIT(head) {                        \
  189.     (head)->cqh_first = (void *)(head);                \
  190.     (head)->cqh_last = (void *)(head);                \
  191. }
  192.  
  193. #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) {        \
  194.     (elm)->field.cqe_next = (listelm)->field.cqe_next;        \
  195.     (elm)->field.cqe_prev = (listelm);                \
  196.     if ((listelm)->field.cqe_next == (void *)(head))        \
  197.         (head)->cqh_last = (elm);                \
  198.     else                                \
  199.         (listelm)->field.cqe_next->field.cqe_prev = (elm);    \
  200.     (listelm)->field.cqe_next = (elm);                \
  201. }
  202.  
  203. #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) {        \
  204.     (elm)->field.cqe_next = (listelm);                \
  205.     (elm)->field.cqe_prev = (listelm)->field.cqe_prev;        \
  206.     if ((listelm)->field.cqe_prev == (void *)(head))        \
  207.         (head)->cqh_first = (elm);                \
  208.     else                                \
  209.         (listelm)->field.cqe_prev->field.cqe_next = (elm);    \
  210.     (listelm)->field.cqe_prev = (elm);                \
  211. }
  212.  
  213. #define CIRCLEQ_INSERT_HEAD(head, elm, field) {                \
  214.     (elm)->field.cqe_next = (head)->cqh_first;            \
  215.     (elm)->field.cqe_prev = (void *)(head);                \
  216.     if ((head)->cqh_last == (void *)(head))                \
  217.         (head)->cqh_last = (elm);                \
  218.     else                                \
  219.         (head)->cqh_first->field.cqe_prev = (elm);        \
  220.     (head)->cqh_first = (elm);                    \
  221. }
  222.  
  223. #define CIRCLEQ_INSERT_TAIL(head, elm, field) {                \
  224.     (elm)->field.cqe_next = (void *)(head);                \
  225.     (elm)->field.cqe_prev = (head)->cqh_last;            \
  226.     if ((head)->cqh_first == (void *)(head))            \
  227.         (head)->cqh_first = (elm);                \
  228.     else                                \
  229.         (head)->cqh_last->field.cqe_next = (elm);        \
  230.     (head)->cqh_last = (elm);                    \
  231. }
  232.  
  233. #define    CIRCLEQ_REMOVE(head, elm, field) {                \
  234.     if ((elm)->field.cqe_next == (void *)(head))            \
  235.         (head)->cqh_last = (elm)->field.cqe_prev;        \
  236.     else                                \
  237.         (elm)->field.cqe_next->field.cqe_prev =            \
  238.             (elm)->field.cqe_prev;                \
  239.     if ((elm)->field.cqe_prev == (void *)(head))            \
  240.         (head)->cqh_first = (elm)->field.cqe_next;        \
  241.     else                                \
  242.         (elm)->field.cqe_prev->field.cqe_next =            \
  243.             (elm)->field.cqe_next;                \
  244. }
  245. #endif    /* !_QUEUE_H_ */
  246.